home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
source
/
vr386
/
lighting.asm
< prev
next >
Wrap
Assembly Source File
|
1993-12-27
|
6KB
|
265 lines
TITLE LIGHTING - MATH FOR LIGHTING IN ASSEMBLER
COMMENT $
/* Routines for cosine or other lighting */
/* All code and algorithms created by Dave Stampe */
/* converted to assembly 17/12/93 by Dave Stampe */
// All algorithms and code (c) 1993 by Dave Stampe
/*
This code is part of the REND386 project, created by Dave Stampe and
Bernie Roehl.
Copyright 1992, 1993, 1994 by Dave Stampe and Bernie Roehl.
May be freely used to write software for release into the public domain;
all commercial endeavours MUST contact BOTH Bernie Roehl and Dave Stampe
for permission to incorporate any part of this software into their
products! Usually there is no charge for under 50-100 items for
low-cost or shareware, and terms are reasonable. Any royalties are used
for development, so equipment is often acceptable payment.
ATTRIBUTION: If you use any part of this source code or the libraries
in your projects, you must give attribution to REND386, Dave Stampe,
and Bernie Roehl in your documentation, source code, and at startup
of your program. Let's keep the freeware ball rolling! No more
code ripoffs please.
CONTACTS: dstampe@psych.toronto.edu, broehl@sunee.uwaterloo.ca
See the COPYRITE.H file for more information.
*/
This code does a very fast computation of cosine for lighting.
It figures N.V/(mag(N)/mag(V) to 8 bit accuracy, where N is the poly
normal, and V is the vector from the lightsource to the polygon.
It is optimized by using the fact that the normls are all scaled to
a known magnitude, and by preshifting V and N so an 8-bit multiply can be
used in the magnitude computation.
A value between -127 and +127 is returned for the cosine (-1.0 to +1.0)
/* Contact: dstampe@sunee.waterloo.edu */
$
.MODEL large
.DATA
; int sqrtable[1024];
; /*integer lookup for square root to 8 bit precision */
extrn _sqrtable
.CODE RENDERING
.386
MULT29 MACRO a,b ; multiply <3.29> -> eax
mov eax,DWORD PTR a
imul DWORD PTR b
shrd eax,edx,29
adc eax,0
ENDM
MMULT29 MACRO a,b,c ; multiply 3 of <3.29> -> eax
mov eax,DWORD PTR a
imul DWORD PTR b
shrd eax,edx,29
adc eax,0
imul DWORD PTR c
shrd eax,edx,29
adc eax,0
ENDM
DOTPROD MACRO a,b,c,x,y,z,p ; dot product plus p, accum in ecx:ebx
mov eax,a ; result in eax
imul DWORD PTR x
mov ecx,edx
mov ebx,eax
mov eax,b
imul DWORD PTR y
add ebx,eax
adc ecx,edx
mov eax,c
imul DWORD PTR z
add eax,ebx
adc edx,ecx
shrd eax,edx,29
adc eax,p
ENDM
;/************** FAST COSINE LIGHT ANGLE COMPUTE **********/
; /* compute vector from light source to surface */
; /* find dot product, normalize by vector length */
; /* returns -128<light<128 (signed 8-bit) */
; /* args: ligh characteristics, poly normal, point on poly */
; /* point on poly is 0,0,0 for spotlight */
;
;int light_cosine(long nx, long ny, long nz,
; long vx, long vy, long vz,
; long lx, long ly, long lz );
nx equ [bp+8] ; arguments
ny equ [bp+12]
nz equ [bp+16]
vx equ [bp+20]
vy equ [bp+24]
vz equ [bp+28]
lx equ [bp+32]
ly equ [bp+36]
lz equ [bp+40]
light equ [bp-4] ; locals
PUBLIC _light_cosine
_light_cosine proc far
push ebp
mov ebp,esp
sub esp,4
push esi ; normal is normalized, just need to
push edi ; find size of light vector
push ecx
push edx
mov eax,DWORD PTR lx ; delta X
sub eax,vx
mov ecx,eax
jge xnn ; abs values -> ecx for scaling
neg ecx
xnn:
mov vx,ecx
mov ebx,ecx
imul DWORD PTR nx ; nx*dx
mov edi,edx
mov esi,eax
mov eax,DWORD PTR ly ; delta Y
sub eax,vy
mov ecx,eax
jge ynn ; abs value
neg ecx
ynn:
mov vy,ecx
or ebx,ecx ; OR abs deltas for scaling test
imul DWORD PTR ny
add esi,eax ; and continue with dot product
adc edi,edx
mov eax,DWORD PTR lz ; same for Z
sub eax,vz
mov ecx,eax
jge znn
neg ecx
znn:
mov vz,ecx
or ebx,ecx
jnz golight ; /* max light at zero distance */
mov ax,127
jmp fincos
golight:
imul DWORD PTR nz
add esi,eax
adc edi,edx ;/* edi:esi now 64-bit dot product */
; START OF LIGHT VECTOR MAG COMPUTE
shrd esi,edi,16 ; prescale
sar edi,16 ; only did the prescale cause bsr
; is so slow on 386
xor cx,cx
test ebx,0ff000000h ; fast size tests, shifts
je not32sig ; will let us use fast mults later
add cx,16
jmp shft16sig
not32sig:
test ebx,0ffff0000h
je nonesig ; prescale by 8 bits */
add cx,8
shft16sig:
shr ebx,cl ; conv. test to word (save 2 us) */
nonesig:
bsr ax,bx ; we test rest of bits
add cx,ax
sub cx,7 ; how many bits to normalize? */
je noshiftn
jl bumpup
shr DWORD PTR vx,cl ; make into 8-bit numbers
shr DWORD PTR vy,cl
shr DWORD PTR vz,cl
shrd esi,edi,cl
sar edi,cl
jmp noshiftn
bumpup:
neg cl
shl DWORD PTR vx,cl
shl DWORD PTR vy,cl
shl DWORD PTR vz,cl
shld edi,esi,cl
shl esi,cl
noshiftn:
mov al,BYTE PTR vx ; now 8-bit diff's: find mag */
mul al
mov bx,ax ; square all components, sum
xor dx,dx
mov al,BYTE PTR vy
mul al
add bx,ax
adc dx,0
mov al,BYTE PTR vz
mul al
add bx,ax
adc dx,0
shrd bx,dx,7 ; lookup in sqrt table */
and ebx,0FFFEh
push esi
les si,DWORD PTR _sqrtable
mov ax,WORD PTR es:[bx+si]
cwde
pop esi
; END OF LIGHT VECTOR MAG COMPUTE
mov ebx,eax
mov edx,edi
mov eax,esi
idiv ebx ; remove magnitude from dot product
fincos: ; result is now in ax: 127*cosine !
pop edx
pop ecx
pop edi
pop esi
mov esp,ebp
pop ebp
ret
_light_cosine endp
end